﻿// ----------------------------------------------------------------------------------
// Sample Code from Fernando Machado Píriz's blog: http://fernandomachadopiriz.com
//
// <copyright company="Fernando Machado Píriz" file="ScreensaverHelper.cs">
// Copyright (c) Fernando Machado Píriz. Distributed under FSF's GPL v2.</copyright>
// ----------------------------------------------------------------------------------
// This code and information are provided "as is" without warranty of any kind,
// either expressed of implied, including but not limited to the implied warranties
// of merchantability and/or fitness for a particular purpose.
// ----------------------------------------------------------------------------------
namespace Screensaver
{
    using System;
    using System.Security.AccessControl;
    using Microsoft.Win32;

    /// <summary>
    /// Provides access to the currently configured screen server.
    /// </summary>
    /// <remarks>Currently configured screen saver is stored in Windows Registry under HKCU\Control Panel\Desktop\CSRNSAVE.EXE.</remarks>
    public static class ScreensaverHelper
    {
        /// <summary>
        /// The name of the Windows registry key storing the active screensaver.
        /// </summary>
        private const string DesktopKeyName = @"Control Panel\Desktop";

        /// <summary>
        /// The name of the Windows registry value storing the active screensaver.
        /// </summary>
        private const string ScreenSaverValueName = "SCRNSAVE.EXE";

        /// <summary>
        /// Gets or sets the value of the currentely configure screen server or <code>null</code> if no screen server has been configured.
        /// </summary>
        public static string Value
        {
            get
            {
                return GetScreenSaverValue();
            }

            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    DeleteScreenSaverValue();
                }
                else
                {
                    SetScreenSaverValue(value);
                }
            }
        }

        /// <summary>
        /// Gets the value of the currently configured screensaver.
        /// </summary>
        /// <returns>The currently configured screensaver from registry.</returns>
        private static string GetScreenSaverValue()
        {
            string result = null;
            RegistryKey hkcu = Registry.CurrentUser;
            RegistryKey desktopKey = hkcu.OpenSubKey(DesktopKeyName);
            try
            {
                var value = desktopKey.GetValue(ScreenSaverValueName);

                if (value != null)
                {
                    result = value.ToString();
                }
            }
            finally
            {
                desktopKey.Close();
            }

            return result;
        }

        /// <summary>
        /// Clears screenserver settingsManager from registry.
        /// </summary>
        private static void DeleteScreenSaverValue()
        {
            RegistryKey hkcu = Registry.CurrentUser;
            RegistryKey desktopKey = hkcu.OpenSubKey(DesktopKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl);
            try
            {
                desktopKey.DeleteValue(ScreenSaverValueName);
            }
            finally
            {
                desktopKey.Close();
            }
        }

        /// <summary>
        /// Sets the screenserver settingsManager in the registry with given value.
        /// </summary>
        /// <param name="value">The value of the screensaver settingsManager to set.</param>
        private static void SetScreenSaverValue(string value)
        {
            RegistryKey hkcu = Registry.CurrentUser;
            RegistryKey desktopKey = hkcu.OpenSubKey(DesktopKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl);
            try
            {
                desktopKey.SetValue(ScreenSaverValueName, value);
            }
            finally
            {
                desktopKey.Close();
            }
        }
    }
}
